import ol from '@/static/openlayers/ol.js';
export const EPSG3857 = 'EPSG:3857';
export const EPSG4326 = 'EPSG:4326';
export const BD09 = 'BD:09';
export const Amapkey = "8e1905be7310447c0576794ea2372a40";
export const mouseposition = () => new ol.control.MousePosition({
  coordinateFormat: coordinate => ol.coordinate.format(coordinate, '当前坐标：经度:{x} &nbsp;纬度:{y}', 4),
  projection: 'EPSG:4326',
  className: 'mousePositionValue',
  target: document.getElementById('mousePositionBar')
});
export const scaleline = (map) => {
  return new ol.control.ScaleLine({
    units: "metric", //设置单位, degrees,imperial,us,nautical,metric
  })
};
/*方形 圆*/
export const createRegularPolygon =  ol.interaction.Draw.createRegularPolygon(4);
/*矩形*/
export const createRectangle =  ol.interaction.Draw.createBox();
/*获取视口四至*/
export const getExent4 =  (map) => map.getView().calculateExtent();
/* 初始化绘制元素*/
export const initDrawElements = {
  //根据类型生成要素
  FeatureFactory: (featureTpye,coordinate) => {
    switch(featureTpye){
      case 'Point':{
        return new ol.Feature({
          geometry: new ol.geom.Point(coordinate)
        })
        break;
      }         
      case 'LineString':{
        return new ol.Feature({
          geometry: new ol.geom.LineString([coordinate[0],coordinate[1]])
        })
        break;
      }
      case 'Circle': {
        let circleIn3857 = new ol.geom.Circle(transform(coordinate[0], 'EPSG:4326', 'EPSG:3857'),coordinate[1],'XY');
        let circleIn4326 = circleIn3857.transform('EPSG:3857','EPSG:4326');
        return new ol.Feature({
          geometry: circleIn4326
        })
       break;
      }
      case 'Square': {
        let circleIn3857 = new ol.geom.Circle(transform(coordinate[0], 'EPSG:4326', 'EPSG:3857'), coordinate[1],'XY');
        let circleIn4326 = circleIn3857.transform('EPSG:3857','EPSG:4326');
        let Square = new ol.geom.Polygon.fromCircle(circleIn4326, 4 ,150)
        return new ol.Feature({
          geometry:  Square
        })
      }
      case 'Rectangle':{
        let Rectangle = new ol.geom.Polygon.fromExtent(coordinate)
        let ret = null
        try{
          ret = new ol.Feature({
            geometry: Rectangle
          })
          return ret;
        }
        catch(ex){
          this.$message.error(ex)
          return;
        }

      }
      case 'Polygon':{
        let Polygon = new ol.Polygon([coordinate])
        return new olFeature({
          geometry: Polygon
        })
      }
    }
  },
  /**
   * 根据类型生成样式
   * 后面可以封装成一个函数，根据用户的输入生成各种要素的类型
   *  */
  StyleFactory: (featureTpye, label) => {
    switch(featureTpye) {
      case 'Point': {
        return new ol.style.Style({
          // image: new ol.style.Circle({
          //   radius: 10,
          //   fill: new ol.style.Fill({ color: "red", opacity: 1 })
          // }),
          text: new ol.style.Text({ //文本样式
            font: '12px Calibri,sans-serif',
            text: label,
            fill: new ol.style.Fill({
              color: 'white'
            }),
            offsetY: -55,
            stroke: new ol.style.Stroke({
              color: 'red',
              width: 2
            }),
          }),
          image: new ol.style.Icon({
              anchor: [0.5, 80],
              anchorXUnits: 'fraction',
              anchorYUnits: 'pixels',
              scale: .6,
              src: require('./img/8.png')
            })
        })
        
      }
      case 'LineString': {
        return new ol.style.Style({
           //填充色
           fill: new Fill({
             color: 'rgba(255, 255, 255, 0.2)'
           }),
           //边线颜色
           stroke: new ol.style.Stroke({
              color: '#0099FF',
              width: 5
           }),
           //形状
           image: new ol.style.Circle({
              radius: 7,
              fill: new ol.style.Fill({
                  color: '#ffcc33'
              })
           })
        })
      }
      case 'Circle': {
        return new ol.style.Style({
          //填充色
          fill: new ol.style.Fill({
            color: 'rgba(255, 255, 255, 0.5)'
          }),
          //边线颜色
          stroke: new ol.style.Stroke({
              color: '#0099FF',
              width: 6
          }),
          //形状
          image: new ol.style.Circle({
              radius: 7,
              fill: new Fill({
                  color: '#ffcc33'
              })
          })
        })
      }
      case 'Square': {
        return new ol.style.Style({
          //填充色
          fill: new ol.style.Fill({
            color: 'rgba(255, 255, 255, 0.8)'
          }),
          //边线颜色
          stroke: new ol.style.Stroke({
              color: 'red',
              width: 2
          }),
          //形状
          image: new ol.style.Circle({
              radius: 7,
              fill: new Fill({
                  color: '#0099FF'
              })
          })
        })
      }
      case 'Polygon': {
        return new ol.style.Style({
          //填充色
          fill: new ol.style.Fill({
            color: 'rgba(255, 255, 255, 0.8)'
          }),
          //边线颜色
          stroke: new ol.style.Stroke({
              color: '#0099FF',
              width: 2
          }),
          //形状
          image: new ol.style.Circle({
              radius: 7,
              fill: new ol.style.Fill({
                  color: '#0099FF'
              })
          })
        })
      }
    }
  },

  DrawVectorSource : () => new ol.source.Vector(),

  LayerVector:(name) => new ol.layer.Vector({name})
}
/* 初始化Draw元素*/
export const interactionDrawFunc = (source, data) => {
  return new ol.interaction.Draw({
    source,
    type: data.type,
    geometryFunction: data.geometry,
    maxPoints: data.maxPoints,
    style: data.style
 })
}
/* 构建source 和 layer*/
export function __checkLayerVector(map, layer, source) {
  if (!this[source]) this[source] = initDrawElements.DrawVectorSource();
  if (!this[layer]) {
    this[layer] = initDrawElements.LayerVector(layer);
    this[layer].setSource(this[source]);
    map.addLayer(this[layer]);
  };
  return {
    layer: this[layer],
    source: this[source]
  };
}
export function __checkInteractDraw(map, draw, source, shape) {
  let geometryFunction = undefined;
  if (this[draw] !== null) map.removeInteraction(this[draw]);
  if (shape === 'Square' || shape === 'LineString') geometryFunction = createRectangle;
  this[draw] = interactionDrawFunc(this[source], {type: shape, geometryFunction});
  map.addInteraction(this[draw]);
  return this[draw];
}
/** 通过属性查找图层 */
export function __findLayer(map, attr, val) {
  const layers = map.getLayers().getArray();
  return layers.find(item => item.get(attr) === val);
}
// 删除featrues
export function removeFeatures(source, name) {
  const features = source.getFeatures();
  features.forEach(feature => {
    if (feature.id_.includes(name)) {
      source.removeFeature(feature);
    }
  });
}
export const Measures = {
  draw: null,
  helpMsg: '',
  sketch: null,             // 当前绘制的要素
  helpTooltipElement: null, // 帮助工具提示元素。
  helpTooltip: null,          // 覆盖以显示帮助消息.
  measureTooltipElement: null,// 度量工具提示元素
  measureTooltip: null,       // 覆盖以显示测量值。
  continuePolygonMsg: '继续点击绘制多边形',     // 用户绘制多边形时显示的消息
  continueLineMsg: '继续点击绘制线',            // 用户绘制线条时显示的消息
  measures(map, measureType, VectorSource) {   // 传入3个参数，map 绘制类型 矢量图层
    let _this = this;
    map.on('pointermove', pointerMoveHandler);

    map.getViewport().addEventListener('mouseout', function () {
      _this.helpTooltipElement.classList.add('hidden');
    });

    // 绘制前-2
    function addInteraction() {
      map.removeInteraction(_this.draw);
      measureType = measureType == 'area' ? 'Polygon' : 'LineString';
      _this.draw = new ol.interaction.Draw({
        source: VectorSource,
        type: measureType,
        style: style()
      });
      map.addInteraction(_this.draw);
      createMeasureTooltip();
      createHelpTooltip();
      var listener;

      _this.draw.on('drawstart', function (evt) {
        _this.sketch = evt.feature;
        var tooltipCoord = evt.coordinate;
        listener = _this.sketch.getGeometry().on('change', function (evt) {
          var geom = evt.target;
          var output;
          if (geom instanceof ol.geom.Polygon) {
            output = formatArea(geom);
            tooltipCoord = geom.getInteriorPoint().getCoordinates();
          }
          else if (geom instanceof ol.geom.LineString) {
            output = formatLength(geom);
            tooltipCoord = geom.getLastCoordinate();
          }
          _this.measureTooltipElement.innerHTML = output;
          _this.measureTooltip.setPosition(tooltipCoord);
        });
      });
      _this.draw.on('drawend', function (e) {
        _this.measureTooltipElement.className = 'ol-tooltip ol-tooltip-static';
        _this.measureTooltip.setOffset([0, -7]);
        _this.sketch = null;  // unset sketch
        _this.measureTooltipElement = null;  // 取消设置工具提示以便可以创建新的工具提示
        createMeasureTooltip();
        ol.Observable.unByKey(listener);
        map.removeInteraction(_this.draw);
        map.removeOverlay(_this.helpTooltip);
      });
    }
    function style() {
      return new ol.style.Style({
        fill: new ol.style.Fill({ color: 'rgba(255, 255, 255, 0.2)' }),
        stroke: new ol.style.Stroke({ color: '#0099FF', solid: [10, 10], width: 2 }),
        image: new ol.style.Circle({ radius: 5, stroke: new ol.style.Stroke({ color: 'rgba(0, 0, 0, 0.7)' }),
        fill: new ol.style.Fill({ color: 'rgba(255, 255, 255, 0.2)' })
        })
      })
    }
    // 创建新的帮助工具提示
    function createHelpTooltip() {
      if (_this.helpTooltipElement) {
        _this.helpTooltipElement.parentNode.removeChild(_this.helpTooltipElement);
      }
      _this.helpTooltipElement = document.createElement('div');
      _this.helpTooltipElement.className = 'ol-tooltip hidden';
      _this.helpTooltip = new ol.Overlay({
        element: _this.helpTooltipElement,
        offset: [15, 0],
        positioning: 'center-left',
      });
      map.addOverlay(_this.helpTooltip);
    }
    // 创建新的度量工具提示-3
    function createMeasureTooltip() {
      if (_this.measureTooltipElement) {
        _this.measureTooltipElement.parentNode.removeChild(_this.measureTooltipElement);
      }
      _this.measureTooltipElement = document.createElement('div');
      _this.measureTooltipElement.className = 'ol-tooltip ol-tooltip-measure';
      _this.measureTooltip = new ol.Overlay({
        element: _this.measureTooltipElement,
        offset: [0, -15],
        positioning: 'bottom-center',
      });
      map.addOverlay(_this.measureTooltip);
    }
    // 移动提示节点-1
    function pointerMoveHandler(evt) {
      if (evt.dragging) return
      _this.helpMsg = '单击开始绘制';
      if (_this.sketch) {
        let geom = _this.sketch.getGeometry();
        if (geom instanceof ol.geom.Polygon) { _this.helpMsg = _this.continuePolygonMsg; }
        else if (geom instanceof ol.geom.LineString) { _this.helpMsg = _this.continueLineMsg; }
      }
      _this.helpTooltipElement.innerHTML = _this.helpMsg;
      _this.helpTooltip.setPosition(evt.coordinate);
      _this.helpTooltipElement.classList.remove('hidden');
    }
    addInteraction();
    // 长度测量
    function formatLength(line) {
      var length = ol.sphere.getLength(line);
      var output;
      if (length > 100) {
        output = Math.round((length / 1000) * 100) / 100 + ' ' + 'km';
      } else {
        output = Math.round(length * 100) / 100 + ' ' + 'm';
      }
      return output;
    }
    // 区域测量
    function formatArea(polygon) {
      var area = ol.sphere.getArea(polygon);
      var output;
      if (area > 10000) {
        output = Math.round((area / 1000000) * 100) / 100 + ' ' + 'km<sup>2</sup>';
      } else {
        output = Math.round(area * 100) / 100 + ' ' + 'm<sup>2</sup>';
      }
      return output;
    }
  },
  // 移除测量动作
  removeInteraction(map) {
    map.removeInteraction(this.draw);
    map.removeOverlay(this.helpTooltip);
  },
};
export function popOverlay() {
  return new ol.Overlay({
    element: document.getElementById("popup-info"),
    offset: [-27, -28],
    autoPan: true,
    positioning: 'bottom-left',
    });
};
export const QuerySpace = {
  draw: null,
  helpMsg: "",
  sketch: null,                          // 当前绘制的要素
  helpTooltipElement: null,              // 帮助工具提示元素。
  helpTooltip: null,                     // 覆盖以显示帮助消息.
  measureTooltipElement: null,           // 度量工具提示元素
  measureTooltip: null,                  // 覆盖以显示测量值。
  continuePolygonMsg: "双击结束绘制",     // 用户绘制多边形时显示的消息
  continueLineMsg: "继续点击绘制线",      // 用户绘制线条时显示的消息
  selectionPolygon(map, source, draw) {
    return new Promise(resolve => {
      const result = new Promise(resolve => {
        const listener = this.clearExcess.call(this, draw, map);
        draw.on('drawend', evt => {
          this.action.call(this, evt.feature.getGeometry(), 'polygon', listener, map);
          setTimeout(resolve.bind(null, evt.feature.getGeometry().getCoordinates()[0]));
        })
      });
      result.then(data => setTimeout(resolve({ data, msg: "success"})));
    });
  },
  clearExcess(draw, map) {
    const stopevent = document.querySelectorAll('.close-drawing-tip');
    const parent = stopevent[0] && stopevent[0].parentNode || [];
    if (stopevent.length) {
      for (let i = 0; i < stopevent.length; i++ ) {
        parent.removeChild(stopevent[i])
      }
    }
    map.on('pointermove', this.pointerMoveHandler.bind(this));
    this.createMeasureTooltip(map);
    this.createHelpTooltip(map);
    var listener;
    draw.on('drawstart', evt => {
      this.sketch = evt.feature;
      listener = evt.feature.getGeometry().on('change', (event) => {
        this.measureTooltipElement.innerHTML = '';
      });
    });
    return listener
  },
  createHelpTooltip(map) {
    if (this.helpTooltipElement) {
      this.helpTooltipElement.parentNode.removeChild(this.helpTooltipElement);
    }
    this.helpTooltipElement = document.createElement('div');
    this.helpTooltipElement.className = 'ol-tooltip hidden';
    this.helpTooltip = new ol.Overlay({
      element: this.helpTooltipElement,
      offset: [15, 0],
      positioning: 'center-left',
    });
    map.addOverlay(this.helpTooltip);
  },
  createMeasureTooltip(map) {
    if (this.measureTooltipElement) {
      this.measureTooltipElement.parentNode.removeChild(this.measureTooltipElement);
    }
    this.measureTooltipElement = document.createElement('span');
    this.measureTooltipElement.className = 'ol-tooltip ol-tooltip-measure';
    this.measureTooltip = new ol.Overlay({
      element: this.measureTooltipElement,
      className: 'close-drawing-tip',
      offset: [0, -15],
      positioning: 'bottom-center',
    });
    map.addOverlay(this.measureTooltip);
  },
  action(geometry, Type, listener, map) {
    var coordinate = geometry.getCoordinates();
    this.measureTooltip && this.measureTooltip.element.setAttribute('title', '清除本次绘制');
    var letter = 0;
    if (Type === 'polygon') letter = 2;
    if (Type === 'point') letter = coordinate[0].length-1;
    if (Type === 'polygon') this.measureTooltip.setPosition(coordinate[0][letter]); // 针对 polygon
    this.measureTooltipElement.className = 'clear-drawing el-icon-close';
    this.measureTooltip.setOffset([0, 0]);
    this.sketch = null;

    this.measureTooltipElement = null;  // 取消设置工具提示以便可以创建新的工具提示
    this.createMeasureTooltip(map);
    ol.Observable.unByKey(listener);
    map.removeInteraction(this.draw);
    map.removeOverlay(this.helpTooltip);
  },
  pointerMoveHandler(evt) {
    if (evt.dragging) return;
    this.helpMsg = '单击开始绘制';
    if (this.sketch) {
      let geom = this.sketch.getGeometry();
      if (geom instanceof ol.geom.Polygon) { this.helpMsg = this.continuePolygonMsg;}
      else if (geom instanceof ol.geom.LineString) { this.helpMsg = this.continueLineMsg;}
    }
    this.helpTooltipElement.innerHTML = this.helpMsg;
    this.helpTooltip.setPosition(evt.coordinate);
    this.helpTooltipElement.classList.remove('hidden');
  }
}